﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using CrawlerCore;
using HtmlAgilityPack;
using WapCrawlerLib;

namespace WapCrawlerCore.WapCrawler
{
    public class AlomobWapSite : WapSiteBase
    {
        public AlomobWapSite(int wapCrawlerId)
            : base(wapCrawlerId)
        {
            ////Init browser session
            //Browser = new BrowserSession_General();

            ////Init the wapsite
            //objWapCrawler = _dc.WapCrawlers.Single(p => p.wapCrawlerId == 1);
        }

        /// <summary>
        /// Start get all posts of id topic
        /// </summary>
        public override  void StartCrawler()
        {
            //string pageUrl = GeneralClass.GetFullUrl(objWapCrawler.wapSiteUrl, objWapCrawler.recentCrawlerUrl);
            //Get items of first page
            GetPages(objWapCrawler.wapSiteUrl, objWapCrawler.recentCrawlerUrl);
        }

        /// <summary>
        /// Step1: Lấy các trang kế tiếp của topic
        /// </summary>
        /// <param name="wapUrl"></param>
        /// <param name="crawlerUrl"></param>
        public override void GetPages(string wapUrl, string crawlerUrl)
        {
            string pageUrl = GeneralClass.GetFullUrl(wapUrl, crawlerUrl);
            //Get items of page and return next page
            string nextPageUrl = GetItemsOfPage(pageUrl);
            //If exist next page then continue load next page
            if (nextPageUrl != string.Empty)
            {
                nextPageUrl = nextPageUrl.Replace(objWapCrawler.wapSiteUrl, "");
                objWapCrawler.recentCrawlerUrl = nextPageUrl;
                _dc.SubmitChanges();
                GetPages(wapUrl, nextPageUrl);
            }
        }

        /// <summary>
        /// Step2: Lấy các link bài viết trong một trang
        /// </summary>
        /// <param name="pageUrl"></param>
        /// <returns></returns>
        public override string GetItemsOfPage(string pageUrl)
        {
            string nextPageUrl = "";
            HtmlDocument doc = Browser.Get(GeneralClass.GetFullUrl(objWapCrawler.wapSiteUrl, pageUrl));
            HtmlNodeCollection nodeCollection = doc.DocumentNode.SelectNodes(@"//body/p/a");
            if (nodeCollection != null)
            {
                Parallel.ForEach(nodeCollection, node =>
                {
                    if (node.Attributes["href"].Value == "index.php?lg=en" ||
                        node.Attributes["href"].Value == "../main.php?lg=en")
                    {
                        string homepage = node.Attributes["href"].Value;
                    }
                    else if (node.InnerHtml.ToLower() == "next>>")
                    {
                        nextPageUrl = GeneralClass.GetFullUrl(objWapCrawler.wapSiteUrl, node.Attributes["href"].Value);
                    }
                    else if (node.InnerHtml.ToLower().Contains("back") ||
                             node.InnerHtml.ToLower().Contains("<>"))
                    {
                        string backPageUrl = GeneralClass.GetFullUrl(objWapCrawler.wapSiteUrl, node.Attributes["href"].Value);
                    }
                    else
                    {
                        //infor of a item
                        string href = node.Attributes["href"].Value;
                        string title = node.InnerHtml;
                        GetItem(href, title,"","");

                    }
                });
            }
            return nextPageUrl;

        }

        /// <summary>
        /// Step3: Lấy đầy đủ thông tin của bài viết
        /// </summary>
        /// <param name="itemUrl"></param>
        /// <param name="title"></param>
        public override void GetItem(string itemUrl, string title, string headContent, string thumbnailUrl)
        {
            WapDataClassesDataContext dc = new WapDataClassesDataContext();

            //========================================================
            //Lấy topic trong bài post
            int topicValue = -1;
            Regex r = new Regex(@"cat_id=(?<cat_id>\d+)");
            Match m = r.Match(itemUrl);
            if (m.Success)
                topicValue = int.Parse(m.Result("${cat_id}"));

            //========================================================
            //Tạo Topic nếu chưa có, nếu có rồi thì load Topic
            TopicCrawler objTopic = new TopicCrawler();    
            try
            {
                objTopic = dc.TopicCrawlers.Single(p => p.topicValue == topicValue && p.wapCrawlerId == objWapCrawler.wapCrawlerId);
            }
            catch
            {
                objTopic.topicValue = topicValue;
                dc.TopicCrawlers.InsertOnSubmit(objTopic);
                dc.SubmitChanges();
            }

            //========================================================
            //Tạo Post nếu chưa có, nếu có rồi thì load
            PostCrawler objPostCrawler = new PostCrawler();
            try
            {
                objPostCrawler = dc.PostCrawlers.Single(p => p.postUrl == itemUrl);
            }
            catch
            {
                objPostCrawler.postUrl = itemUrl;
                objPostCrawler.postTitle = title;
                dc.PostCrawlers.InsertOnSubmit(objPostCrawler);
                dc.SubmitChanges();
            }

            //========================================================
            //Tạo liên kết Topic với Post nếu chưa có, nếu có rồi thì load
            TopicPostCrawler objTopicPostCrawler = new TopicPostCrawler();
            try
            {
                objTopicPostCrawler = dc.TopicPostCrawlers.Single(p => p.topicCrawlerId == objTopic.topicCrawlerId &&
                                                                p.postCrawlerId == objPostCrawler.postCrawlerId);
            }
            catch
            {
                objTopicPostCrawler.topicCrawlerId = objTopic.topicCrawlerId;
                objTopicPostCrawler.postCrawlerId = objPostCrawler.postCrawlerId;
                dc.TopicPostCrawlers.InsertOnSubmit(objTopicPostCrawler);
                dc.SubmitChanges();
            }

            //========================================================
            //Get game id lưu vào trong PostId của Post
            r = new Regex(@"game_id=(?<game_id>\d+)");
            m = r.Match(itemUrl);
            if (m.Success)
            {
                objPostCrawler.postId = int.Parse(m.Result("${game_id}"));
            }

            //========================================================
            //Load page of a item
            HtmlDocument itemDoc = Browser.Get(GeneralClass.GetFullUrl(objWapCrawler.wapSiteUrl, itemUrl));
            if (null==itemDoc)
            {
                return;
            }

            //========================================================
            //Note1: get content of a item
            HtmlNodeCollection nodeCollection = itemDoc.DocumentNode.SelectNodes("//div[@class=\"menu\"]");
            if (nodeCollection != null)
            {
                //Get date upload
                string[] content = Regex.Split(nodeCollection[0].InnerHtml, "<br>");
                //objPost.postContent = Browser.TranslateContent(content[1], 500, "en", "vi")[2];
                objPostCrawler.postContent = content[1];
                string strDate = content[2].ToLower().Replace("time upload:", "").Trim();
                try
                {
                    DateTime dtUpload = DateTime.Parse(strDate, CultureInfo.CreateSpecificCulture("fr-FR"));
                    objPostCrawler.postDate = dtUpload;
                }
                catch
                {

                }

                //Get img itemUrl
                string imgUrl = nodeCollection[0].ChildNodes[0].Attributes["src"].Value;
                //========================================================
                //Tạo Image mới nếu chưa có, nếu có rồi thì load
                ImageCrawler img = new ImageCrawler();
                try
                {
                    img = dc.ImageCrawlers.Single(p => p.imageUrl == imgUrl && p.postCrawlerId == objPostCrawler.postCrawlerId);
                }
                catch
                {
                    img.imageUrl = imgUrl;
                    objPostCrawler.ImageCrawlers.Add(img);
                }

                //ignore first item and last item (it's a main page)
                //Remand items are files
                for (int i = 1; i < nodeCollection.Count; i++)
                {
                    string fileName = nodeCollection[i].ChildNodes[0].InnerHtml;
                    string fileHref = nodeCollection[i].ChildNodes[0].Attributes["href"].Value;
                    
                    HtmlDocument fileDoc = Browser.Get(GeneralClass.GetFullUrl(objWapCrawler.wapSiteUrl, nodeCollection[i].ChildNodes[0].Attributes["href"].Value));
                    string fileUrl = Browser.Response.Headers["location"];
                    //========================================================
                    //Tạo File mới nếu chưa có, nếu có rồi thì load
                    FileCrawler objFileCrawler = new FileCrawler();
                    try
                    {
                        objFileCrawler = dc.FileCrawlers.Single(p => p.fileUrl == fileUrl 
                            && p.postCrawlerId == objPostCrawler.postCrawlerId);

                    }
                    catch
                    {
                        objFileCrawler.fileName = fileName;
                        objFileCrawler.fileUrl = fileUrl;
                        objPostCrawler.FileCrawlers.Add(objFileCrawler);
                    }
                }
            }

            //Crawler a post complete!
            objPostCrawler.crawlerStatus = true;
            dc.SubmitChanges();
        }
    }
}